package com.lanchetech.admin.service.impl;


import com.lanchetech.admin.config.JwtTokenUtil;
import com.lanchetech.admin.service.AdminService;
import com.lanchetech.bean.request.AdminRolePermissionReq;
import com.lanchetech.bean.request.PageReq;
import com.lanchetech.bean.request.SysLogReq;
import com.lanchetech.bean.request.UpdatePasswordReq;
import com.lanchetech.bean.response.BasePageResp;
import com.lanchetech.bean.response.BaseResp;
import com.lanchetech.bean.response.ResultData;
import com.lanchetech.bean.util.PageHelpUtil;
import com.lanchetech.bean.vo.AdminDetailVO;
import com.lanchetech.common.enums.DeletedEnum;
import com.lanchetech.common.enums.MsgUserRoleEnum;
import com.lanchetech.common.enums.ResultCode;
import com.lanchetech.common.enums.ToggleEnum;
import com.lanchetech.dao.*;
import com.lanchetech.entity.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class AdminServiceImpl implements AdminService {

    @Autowired
    AdminMapper adminMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    AdminPermissionMapper adminPermissionMapper;

    @Autowired
    AdminRoleMapper adminRoleMapper;

    @Autowired
    AdminRolePermissionMapper adminRolePermissionMapper;

    @Autowired
    SysLogMapper sysLogMapper;

    @Autowired
    MsgUserMapper msgUserMapper;

    @Autowired
    JwtTokenUtil jwtTokenUtil;

    @Value("${im.jwt.secret}")
    public String secret;

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Override
    public ResultData<AdminDetailVO> getAdminDetail(Admin admin) {
        AdminDetailVO vo = new AdminDetailVO();
        admin.setPassword("");
        BeanUtils.copyProperties(admin, vo);

        MsgUser msgUser = msgUserMapper.findOneByRelateIdAndRole(admin.getId(), MsgUserRoleEnum.ADMIN.getRole());
        vo.setMsgAvatar("https://hipo.oss-cn-hangzhou.aliyuncs.com/resource/hipo/logo.JPG");
        if (msgUser != null) {
            vo.setChatToken(jwtTokenUtil.generateToken(msgUser, secret));
            vo.setMsgUserId(msgUser.getId());
            vo.setMsgNickname(msgUser.getNickname());
            vo.setMsgAvatar(msgUser.getAvatar());
            vo.setMsgServiceName(msgUser.getServiceName());
        }

        return new ResultData<>(vo);
    }

    @Override
    public ResultData<List<AdminPermission>> getAdminPermissions(Admin admin) {
        List<AdminPermission> list = adminPermissionMapper.getAdminPermissionList(admin.getRoleId());
        return new ResultData<>(list);
    }

    @Override
    public ResultData<BasePageResp<AdminRole>> getAdminRolePage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<AdminRole> list = adminRoleMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public BaseResp updatePassword(Admin admin, UpdatePasswordReq req) {
        // 验证老密码
        if (!new BCryptPasswordEncoder().matches(req.getOldPassword(), admin.getPassword())) {
            return new BaseResp(ResultCode.PASSWORD_ERROR);
        }
        // 写入新密码
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String rawPassword = req.getNewPassword();

        Admin updateAdmin = Admin.builder().id(admin.getId()).password(encoder.encode(rawPassword)).lastPasswordResetDate(new Date()).updatedAt(new Date()).build();

        adminMapper.updateByPrimaryKeySelective(updateAdmin);

        return new BaseResp();
    }

    @Override
    public BaseResp editAdminRole(AdminRole adminRole) {
        if (adminRole.getId() == null) {
            AdminRole result = adminRoleMapper.findOneByName(adminRole.getName());
            if (result != null) {
                return new BaseResp(ResultCode.ADMIN_ROLE_IS_EXISTS);
            }
            // 创建
            if (adminRole.getName().startsWith("ROLE_")) {
                adminRoleMapper.insert(adminRole);
                return new BaseResp();
            } else {
                return new BaseResp(ResultCode.ADMIN_ROLE_ERROR);
            }
        } else {
            // 修改
            adminRole.setName(null);
            adminRoleMapper.updateByPrimaryKeySelective(adminRole);
            return new BaseResp();
        }
    }

    @Override
    public BaseResp deleteAdminRole(Long id) {
        if (id.equals(1)) {
            return new BaseResp(ResultCode.FAIL);
        }
        adminRolePermissionMapper.deleteByRoleId(id);
        adminRoleMapper.deleteByPrimaryKey(id);
        return new BaseResp();
    }

    @Override
    public ResultData<List<AdminPermission>> getAdminRolePermissionList(Long id) {
        List<AdminPermission> list = adminRolePermissionMapper.getAdminRolePermissionList(id);
        return new ResultData<>(list);
    }

    @Override
    public ResultData<List<AdminPermission>> getAllPermissionList() {
        List<AdminPermission> list = adminPermissionMapper.findAll();
        return new ResultData<>(list);
    }

    @Override
    public BaseResp updateAdminRolePermission(AdminRolePermissionReq req) {
        adminRolePermissionMapper.deleteByRoleId(req.getRoleId());
        adminRolePermissionMapper.insertAdminRolePermissions(req.getPermissions(), req.getRoleId());
        return new BaseResp();
    }

    @Override
    public ResultData<BasePageResp<Admin>> getAdminPage(PageReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<Admin> list = adminMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<List<Admin>> getAdminList(PageReq req) {
        req.setStatus(ToggleEnum.ON.getStatus());
        return new ResultData<>(adminMapper.findAllPage(req));
    }

    @Override
    public ResultData<List<AdminRole>> getAdminRoleList() {
        return new ResultData<>(adminRoleMapper.findAll());
    }

    @Override
    public BaseResp editAdmin(Admin admin, Admin req) {
        log.info("1111111111111111111111111111111111111111111111111111111");
        // 当前操作的管理员
        if (req.getId() == null) {
            log.info("我进入了if+++++++++++++++++++++++++++++++++++++++++++++");
            // 判断账号是否已经存在
            Admin result = adminMapper.findOneByUsername(req.getUsername());
            if (result != null && result.getDeleted() == 0) {
                return new BaseResp(ResultCode.USER_EXISTED);
            }
            // 判断用户名是否已经存在
            Admin oneByNickname = adminMapper.findOneByNickname(req.getNickname());
            if (oneByNickname != null) {
                return new BaseResp(ResultCode.NICKNAME_EXISTED);
            }
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            // 创建管理员
            if (result == null) {
                final String rawPassword = req.getUsername();
                req.setPassword(encoder.encode(rawPassword)).setAvatar("https://lancheshop.oss-cn-hangzhou.aliyuncs.com/resource/default-avatar2.png").setLastPasswordResetDate(new Date()).setCreatedAt(new Date()).setUpdatedAt(new Date()).setDeleted(DeletedEnum.DEFAULT.getStatus()).setStatus(1);
                adminMapper.insert(req);
            } else {
                // 修改已删除的管理员
                req.setId(result.getId());
                req.setPassword(encoder.encode("123456")).setAvatar("https://lancheshop.oss-cn-hangzhou.aliyuncs.com/resource/default-avatar2.png").setLastPasswordResetDate(new Date()).setCreatedAt(new Date()).setUpdatedAt(new Date()).setDeleted(DeletedEnum.DEFAULT.getStatus()).setStatus(1);
                req.setDeleted((byte) 0);
                adminMapper.updateByPrimaryKeySelective(req);
            }

        } else {
            log.info("我进入了else+++++++++++++++++++++++++++++++++++++++++++++");
            Admin result = adminMapper.selectByPrimaryKey(req.getId());
            if (admin.getNickname() != null && !result.getNickname().equals(req.getNickname())) {
                Admin oneByNickname = adminMapper.findOneByNickname(req.getNickname());
                if (oneByNickname != null) {
                    return new BaseResp(ResultCode.NICKNAME_EXISTED);
                }
            }
            // 不能修改超级管理员
            if (req.getId().equals(1L)) {
                return new BaseResp(ResultCode.FAIL);
            }
            req.setUpdatedAt(new Date());
            adminMapper.updateByPrimaryKeySelective(req);
        }
        log.info("2222222222222222222222222222222222222222222");
        return new BaseResp();
    }

    @Override
    public BaseResp deleteAdmin(Admin admin, Long id) {
        // 不能删除超级管理员
        if (id.equals(1L)) {
            return new BaseResp(ResultCode.FAIL);
        }
        adminMapper.updateDeletedById(DeletedEnum.DELETED.getStatus(), id);
        return new BaseResp();
    }

    @Override
    public BaseResp resetAdminPassword(Long id) {
        if (id == 1) {
            return new BaseResp(ResultCode.FAIL);
        }
        Admin admin = adminMapper.selectByPrimaryKey(id);
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String rawPassword = admin.getUsername();
        Admin updateAdmin = Admin.builder().id(id).password(encoder.encode(rawPassword)).lastPasswordResetDate(new Date()).updatedAt(new Date()).build();

        adminMapper.updateByPrimaryKeySelective(updateAdmin);

        return new BaseResp();
    }

    @Override
    public ResultData<Admin> queryAdminDetail(Long id) {
        return new ResultData<>(adminMapper.selectByPrimaryKey(id));
    }

    @Override
    public ResultData<BasePageResp<SysLog>> getSysLogPage(SysLogReq req) {
        Page page = PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<SysLog> list = sysLogMapper.findAllPage(req);
        return PageHelpUtil.buildPage(list, page);
    }

    @Override
    public ResultData<List<Admin>> getPermissionAdmin(Long id) {
        List<AdminRolePermission> adminRolePermissionList = adminRolePermissionMapper.findAllByPermissionId(id);
        List<Admin> admins = new ArrayList<>();
        if (!CollectionUtils.isEmpty(adminRolePermissionList)) {
            admins = adminMapper.findAllByRoles(adminRolePermissionList.stream().map(AdminRolePermission::getRoleId).collect(Collectors.toList()));
        }
        return new ResultData<>(admins);
    }
}